package com.harmontronics.app.pedestal.bridge;

import android.content.Intent;
import android.text.TextUtils;
import android.webkit.JavascriptInterface;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.Utils;
import com.blankj.utilcode.util.ZipUtils;
import com.harmontronics.app.pedestal.AppConstants;
import com.harmontronics.app.pedestal.agent.WebActivity;
import com.harmontronics.app.pedestal.bridge.model.BaseBridge;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.callback.FileCallback;
import com.lzy.okgo.model.Progress;
import com.lzy.okgo.model.Response;
import com.lzy.okgo.request.GetRequest;
import com.lzy.okgo.request.base.Request;
import com.lzy.okserver.OkDownload;
import com.lzy.okserver.download.DownloadListener;
import com.xiasuhuei321.loadingdialog.view.LoadingDialog;

import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import wendu.dsbridge.CompletionHandler;

public class AppBridge extends BaseBridge {
    private LoadingDialog mLoadingDialog;

    @JavascriptInterface
    public String getVersionSync(Object args) {
        LogUtils.d("APP.getVersionSync");
        return success(AppUtils.getAppVersionCode());
    }

    @JavascriptInterface
    public void getVersion(Object args, CompletionHandler<String> handler) {
        LogUtils.d("APP.getVersion");
        handler.complete(success(AppUtils.getAppVersionCode()));
    }

    @JavascriptInterface
    public String getLangSync(Object args) {
        LogUtils.d("APP.getLangSync");
        return success(Utils.getApp().getResources().getConfiguration().locale.getLanguage());
    }

    @JavascriptInterface
    public void getLang(Object args, CompletionHandler<String> handler) {
        LogUtils.d("APP.getLang");
        handler.complete(success(Utils.getApp().getResources().getConfiguration().locale.getLanguage()));
    }

    @JavascriptInterface
    public void update(Object argsJson, CompletionHandler<String> handler) {
        LogUtils.d("APP.update");
        if (null == argsJson) {
            handler.complete(fail("参数不能为空", null));
            return;
        }

        try {
            JSONObject args = (JSONObject) argsJson;
            LogUtils.d("args: " + args.toString());
            if (!args.has("path")) {
                throw new IllegalArgumentException("资源更新路径不能为空");
            }
            String path = args.getString("path");
            if (TextUtils.isEmpty(path)) {
                throw new IllegalArgumentException("资源更新路径不能为空");
            }

            ThreadUtils.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (null == mLoadingDialog) {
                        mLoadingDialog = new LoadingDialog(ActivityUtils.getTopActivity());
                    }
                }
            });

            FileUtils.deleteAllInDir(AppConstants.DOWNLOAD_HTML_FOLDER);

            OkGo.<File>get(path)
                    .tag(AppConstants.DOWNLOAD_RESOURCE_TAG)
                    .execute(new FileCallback() {
                        @Override
                        public void onStart(Request<File, ? extends Request> request) {
                            ThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mLoadingDialog.setLoadingText("更新中")
                                            .setSuccessText("更新成功")
                                            .setFailedText("更新失败")
                                            .closeFailedAnim()
                                            .closeSuccessAnim()
                                            .show();
                                }
                            });
                        }

                        @Override
                        public void onSuccess(Response<File> response) {
                            ThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mLoadingDialog.loadSuccess();
                                }
                            });
                            unZipFiles(response.body(), handler);
                        }

                        @Override
                        public void onError(Response<File> response) {
                            ThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mLoadingDialog.loadFailed();
                                }
                            });
                            handler.complete(fail("更新失败", response.getException()));
                        }

                        @Override
                        public void downloadProgress(Progress progress) {

                        }
                    });
        } catch (Exception e) {
            handler.complete(fail(e.getMessage(), e));
        }
    }

    private void unZipFiles(File file, CompletionHandler<String> handler) {
        Observable.create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(@NotNull ObservableEmitter<String> emitter) throws Exception {
                        try {
                            List<File> files = ZipUtils.unzipFile(file.getAbsolutePath(), AppConstants.DOWNLOAD_HTML_FOLDER);
                            if (null != files && files.size() > 0) {
                                for (int i = 0; i < files.size(); i++) {
                                    File file = files.get(i);
                                    LogUtils.d("unzip file: " + file.toString());
                                    if (file.getAbsolutePath().endsWith(".db")) {
                                        FileUtils.copy(file, Utils.getApp().getDatabasePath(file.getName()));
                                    }
                                }
                            }
                        } catch (IOException e) {
                            emitter.onError(e);
                        }
                        emitter.onNext("");
                        emitter.onComplete();
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) throws Exception {
                        ThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mLoadingDialog.setLoadingText("解压中")
                                        .setSuccessText("解压成功")
                                        .setFailedText("解压失败")
                                        .closeFailedAnim()
                                        .closeSuccessAnim()
                                        .show();
                            }
                        });
                    }
                })
                .doOnNext(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        ThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mLoadingDialog.loadSuccess();
                            }
                        });
                        handler.complete(success("更新成功"));
                        ActivityUtils.startActivity(new Intent(ActivityUtils.getTopActivity(), WebActivity.class));
                    }
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        ThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mLoadingDialog.loadFailed();
                            }
                        });
                        handler.complete(fail("更新失败", throwable));
                    }
                })
                .subscribe();
    }
}
